package main

import (
	"fmt"
	"reflect"
)

// 反射练习
func main() {
	var num float64 = 1.2345
	reflectNum(num)

	user := User{1, "jack", 18}
	parseReflect(user)
}

func reflectNum(arg interface{}) {
	fmt.Println("type: ", reflect.TypeOf(arg))
	fmt.Println("value: ", reflect.ValueOf(arg))
}

type User struct {
	Id   int
	Name string
	Age  int
}

func (this *User) Call() {
	fmt.Println("user is called ..")
	fmt.Printf("%v\n", this)
}

func parseReflect(input interface{}) {
	inputType := reflect.TypeOf(input)
	fmt.Println("inputType: ", inputType.Name())

	inputValue := reflect.ValueOf(input)
	fmt.Println("inputValue: ", inputValue)

	for i := 0; i < inputType.NumField(); i++ {
		fmt.Println("field: ", inputType.Field(i).Name)
		fmt.Println("value: ", inputValue.Field(i))
	}

	for i := 0; i < inputType.NumMethod(); i++ {
		fmt.Println("method: ", inputType.Method(i).Name)
		fmt.Println("value: ", inputValue.Method(i))

		method := inputType.Method(i)
		method.Func.Call([]reflect.Value{})
	}
}
